package bavaria.hightech.banking;

import bavaria.hightech.banking.GiroKonto;
import bavaria.hightech.banking.FestgeldKonto;
import bavaria.hightech.geld.Money;
import bavaria.hightech.geld.Waehrung;
import bavaria.hightech.konditionen.FestgeldKonditionen;
import bavaria.hightech.konditionen.FestgeldKonditionen.Laufzeit;
import bavaria.hightech.konditionen.GiroKonditionen;
import bavaria.hightech.konditionen.GiroKonditionen.BoniGruppe;
import bavaria.hightech.konditionen.Konditionen;

public class BankImpl implements BankKundenSicht, BankAdministration{

	private FestgeldKonditionen[] festKonList = new FestgeldKonditionen[10];
	private FestgeldKonditionen festkon = new FestgeldKonditionen(Laufzeit.ONE);
	private FestgeldKonditionen festkon2 = new FestgeldKonditionen(Laufzeit.THREE);
	private FestgeldKonditionen festkon3 = new FestgeldKonditionen(Laufzeit.TWELVE);
	int counterFest = 3;
	
	private GiroKonditionen[] giroKonList = new GiroKonditionen[10];
	private GiroKonditionen girokon = new GiroKonditionen(BoniGruppe.EINS);
	private GiroKonditionen girokon2 = new GiroKonditionen(BoniGruppe.ZWEI);
	private GiroKonditionen girokon3 = new GiroKonditionen(BoniGruppe.DREI);
	private int counterGiro = 3;
	private int counter = 0;
	
	private Konto[] konto;
	int kontonummer = 1000;
	
	public BankImpl(){
		konto = new Konto[10];
		setFestKon();
		setGiroKon();
		
	}
	

	@Override
	public void setGiroHabenzins(long habenzins){
		girokon.hz = habenzins;
		girokon2.hz = habenzins;
		girokon3.hz = habenzins;
	}
	
	@Override
	public void setGiroSollzins(long sollzins){
		girokon.sz = sollzins;
		girokon2.sz = sollzins;
		girokon3.sz = sollzins;
	}
	
	private void setGiroKon(){
		giroKonList[0] = girokon;
		giroKonList[1] = girokon2;
		giroKonList[2] = girokon3;
	}
	
	private void setFestKon(){
		festKonList[0] = festkon;
		festKonList[1] = festkon2;
		festKonList[2] = festkon3;
	}
	
	public FestgeldKonditionen getFestKon(String laufzeit){
		if(laufzeit == festKonList[0].lauf.toString())
			return festKonList[0];
		else if(laufzeit == festKonList[1].lauf.toString())
			return festKonList[1];
		else 
			return festKonList[2];
	}
	
	private GiroKonditionen getGiroKon(BoniGruppe boni){
		if(boni == BoniGruppe.EINS){
			return giroKonList[0];
		}
		else if(boni == BoniGruppe.ZWEI){
			return giroKonList[1];
		}
		else {
			return giroKonList[2];
		}
	}
	
	private BoniGruppe getGiroBoni(){
		if(counter == 3)
			counter = 0;
		
		if(counter == 0){
			counter++;
			return BoniGruppe.EINS;
		}
		else if(counter == 1){
			counter++;
			return BoniGruppe.ZWEI;
		}
		else {
			counter++;
			return BoniGruppe.DREI;
		}
	}
	
	public Konditionen getKon(int kontonr){
		if(getKonto(kontonr).kontotyp == "GIRO"){
			GiroKonditionen giro = (GiroKonditionen) getKonto(kontonr).getKondition();
			return giro;
		}
		else{
			FestgeldKonditionen festgeld = (FestgeldKonditionen) getKonto(kontonr).getKondition();
			return festgeld;
		}
	}
	
	public Laufzeit getLaufzeit(int kontonr){
		FestgeldKonditionen festgeld = (FestgeldKonditionen) getKonto(kontonr).getKondition();
		return festgeld.lauf;
	}
	
	
	public Konto getKonto(int kontonr) throws ArrayIndexOutOfBoundsException{
		Konto kontoReturn = null;
		try
		{kontoReturn = konto[kontonr-1000];
		}
		catch(ArrayIndexOutOfBoundsException e){
			throw e;
		}
		return kontoReturn;
		
	}
	
	public void neueGiroKondition(BoniGruppe boni){
		GiroKonditionen giro = new GiroKonditionen(boni);
		giroKonList[counterGiro] = giro;
		counterGiro++;
	}
	
	public void neueFestgeldkondition(Laufzeit lauf){
		FestgeldKonditionen fest = new FestgeldKonditionen(lauf);
		festKonList[counterFest] = fest;
		counterFest++;
	}
	
	
	@Override
	public void neuesFestgeldkonto(String name, String laufzeit, Waehrung wa) {
		Money money = new Money(0, wa);
		FestgeldKonto fest = new FestgeldKonto(kontonummer, name, getFestKon(laufzeit), money, "FESTGELD");
		konto[kontonummer-1000] = fest;
		kontonummer++;
	}
	
	@Override
	public void neuesGirokonto(String name, Waehrung wa) {
		Money money = new Money(0, wa);
		GiroKonto giro = new GiroKonto(kontonummer, name, getGiroKon(getGiroBoni()), money, "GIRO");
		konto[kontonummer-1000] = giro;
		kontonummer++;
	}

	
	@Override
	public String getKontostand(int kontonr) {
		String s = "Kontostand von Konto " + kontonr + ": " + getKonto(kontonr).kontostand.betrag + " " + getKonto(kontonr).kontostand.waehrung;
		return s;
		
	}

	@Override
	public void einzahlen(int kontonr, Money money) {
		try
		{
			getKonto(kontonr).zugang(money, "Einzahlung");
		}
		catch(ArrayIndexOutOfBoundsException e){
			System.out.println("Kontonummer " + kontonr + " nicht vorhanden!");
		}
	}

	@Override
	public void abheben(int kontonr, Money money) {
		try
		{
			getKonto(kontonr).abgang(money, "Auszahlung");
		}
		catch(ArrayIndexOutOfBoundsException e){
			System.out.println("Kontonummer " + kontonr + " nicht vorhanden!");
		}
	}

	@Override
	public void transaktion(int kontonr, Money money, String grund, int kontonr2) {
		try
		{
			getKonto(kontonr).abgang(money, grund);
		}
		catch(ArrayIndexOutOfBoundsException e){
			System.out.println("Kontonummer " + kontonr + " nicht vorhanden!");
			return;
		}
		try
		{
			getKonto(kontonr2).zugang(money, grund);
		}
		catch(ArrayIndexOutOfBoundsException e){
			System.out.println("Kontonummer " + kontonr2 + " nicht vorhanden!");
			getKonto(kontonr).zugang(money, "Falsche Buchung!");
		}
	}
	
	public void verzinsen(){
		for(int i = 1000; i <= konto.length + 1000 & getKonto(i) != null; i++){
			if(getKonto(i).kontotyp == "Giro")
				getKonto(i).verzinsen();
		}
	}
	
	public void verzinsen(Laufzeit laufzeit){
		for(int i = 1000; i <= konto.length + 1000 & getKonto(i) != null; i++){
			if(getKonto(i).kontotyp == "FESTGELD")
				getKonto(i).verzinsen(laufzeit);
		}
	}
	
	private void list(){
		for(int i = 1000; i <= konto.length + 1000 & getKonto(i) != null; i++)
			System.out.println(getKonto(i).toString());
	}
	
	public String kontoauszug(int kontonr){
		return getKonto(kontonr).buchungen();
	}
	
	@Override
	public String konditionToString(){
		StringBuffer sb = new StringBuffer();
		sb.append("Girokonto - Bonitätsgruppe EINS - Bonität: " + girokon.boniBetrag.betrag + " " + girokon.boniBetrag.waehrung + "; Habenzins: " + girokon.hz + "; Sollzins: " + girokon.sz + "\n");
		sb.append("Girokonto - Bonitätsgruppe ZWEI - Bonität: " + girokon2.boniBetrag.betrag + " " + girokon2.boniBetrag.waehrung + "; Habenzins: " + girokon2.hz + "; Sollzins: " + girokon2.sz + "\n");
		sb.append("Girokonto - Bonitätsgruppe DREI - Bonität: " + girokon3.boniBetrag.betrag + " " + girokon3.boniBetrag.waehrung + "; Habenzins: " + girokon3.hz + "; Sollzins: " + girokon3.sz + "\n");
		sb.append("Festgeldkonto - Laufzeit: " + festkon.lauf + " Month; Habenzins: " + festkon.zinssatz + "\n");
		sb.append("Festgeldkonto - Laufzeit: " + festkon2.lauf + " Months; Habenzins: " + festkon2.zinssatz + "\n");
		sb.append("Festgeldkonto - Laufzeit: " + festkon3.lauf + " Months; Habenzins: " + festkon3.zinssatz + "\n");
		
		String s = sb.toString();
		return s;
	}
	
	
	
	
	public static void main(String[] args){
		BankImpl bank = new BankImpl();

//		Money money = new Money(100, Waehrung.EUR);
//		Money money1 = new Money(10, Waehrung.EUR);
//		Money money2 = new Money(512, Waehrung.EUR);
		Money money3 = new Money(3000, Waehrung.EUR);

//		Money money4 = new Money(-4, Waehrung.EUR);
//		Money money5 = new Money(-5, Waehrung.EUR);
//		Money money6 = new Money(-6, Waehrung.EUR);
//		Money money7 = new Money(-7, Waehrung.EUR);
		
		
		bank.neuesGirokonto("0", Waehrung.EUR);
		bank.neuesGirokonto("1", Waehrung.EUR);
		bank.neuesGirokonto("2", Waehrung.EUR);
		bank.neuesGirokonto("3", Waehrung.EUR);
		bank.neuesFestgeldkonto("4", "THREE", Waehrung.EUR);
		bank.neuesFestgeldkonto("5", "ONE", Waehrung.EUR);
		
		System.out.println(bank.getKon(1000));
	}

}
